#pragma once

#include <iostream>
#include <string>
#include <functional>
#include "InetAddr.hpp"
#include "Reactor.hpp"

class Reactor;
class Connection;
using func_t = std::function<void(Connection *)>;

class Connection
{
public:
    Connection(int sock)
        : _sock(sock), _R(nullptr)
    {
    }
    ~Connection()
    {
    }

    void SetEvents(uint32_t events)
    {
        _events = events;
    }

    // 注册就绪时，怎么应对的方法
    void Register(func_t recver, func_t sender, func_t excepter)
    {
        _recver = recver;
        _sender = sender;
        _excepter = excepter;
    }
    void SetSelf(Reactor *R)
    {
        _R = R;
    }
    int Sockfd()
    {
        return _sock;
    }
    uint32_t Events()
    {
        return _events;
    }
    std::string &Inbuffer() // 记住这里是string&返回，因为序列化序列化，Decode时是会截取完整的报文
    {
        return _inbuffer;
    }

    void AppendInbuffer(const std::string &buffer)
    {
        _inbuffer += buffer;
    }

    void AppendOutbuffer(const std::string &buffer)
    {
        _outbuffer += buffer;
    }

    std::string &Outbuffer()
    {
        return _outbuffer;
    }

    void OutbufferRemove(int n)
    {
        _outbuffer.erase(0, n);
    }

    bool OutbufferEmpty()
    {
        return _outbuffer.empty();
    }

    void Close()
    {
        if (_sock >= 0)
            ::close(_sock);
    }

private:
    int _sock;
    std::string _inbuffer;
    std::string _outbuffer;
    InetAddr _addr;
    uint32_t _events;

public:
    func_t _recver;
    func_t _sender;
    func_t _excepter;
    Reactor *_R; // 将来listen套接字也是一个connection对象，而listen套接字accepter获取上新的fd，构建connection时
    // 要能够通过listen套接字的connection找到Reactor，并将新的connection添加到这个Reactor的_connections里面，进管理
};